import sys
import os
import random
import string
from datetime import datetime
from decimal import Decimal
from db import api
from db.models import Base, engine
from common import exceptions, config
from common.utils import UserRole, PurchaseStatus, SaleStatus, PaymentMethod

def random_string(length=8, digits_only=False):
    """生成随机字符串"""
    chars = string.digits if digits_only else string.ascii_letters + string.digits
    return ''.join(random.choices(chars, k=length))

def create_test_data():
    print("开始创建测试数据...")

    # 创建用户数据
    users = create_users()

    # 创建商品分类
    categories = create_categories()

    # 创建商品
    products = create_products(categories)

    # 创建供应商
    suppliers = create_suppliers()

    # 建立商品和供应商的关联（包含成本价）
    link_products_and_suppliers(products, suppliers)

    # 创建客户
    customers = create_customers()

    # 创建采购单并更新状态
    purchases = create_purchases_and_update_status(suppliers, products, users)

    # 创建销售单并更新状态
    sales = create_sales_and_update_status(purchases, customers, products, users)

    # 创建采购退货单
    create_purchase_returns(purchases, users)

    # 创建销售退货单
    create_sale_returns(sales, users)

    print("测试数据创建完成！")

def create_users():
    print("\n===== 创建用户数据 =====")
    user_ids = []
    
    # 创建管理员用户
    admin = api.add_user("admin", "admin123", UserRole.ADMIN)
    user_ids.append(admin["id"])
    print(f"创建管理员用户: admin, ID: {admin['id']}")
    
    # 创建经理用户
    manager = api.add_user("manager", "manager123", UserRole.MANAGER)
    user_ids.append(manager["id"])
    print(f"创建经理用户: manager, ID: {manager['id']}")
    
    # 创建销售员用户
    for i in range(3):
        username = f"saler{i+1}"
        saler = api.add_user(username, f"{username}123", UserRole.SALER)
        user_ids.append(saler["id"])
        print(f"创建销售员用户: {username}, ID: {saler['id']}")
    
    # 返回用户ID列表而不是对象列表
    return user_ids

def create_categories():
    print("\n===== 创建商品分类 =====")
    category_info = []
    
    # 创建主分类
    main_categories = [
        "饮料",
        "零食",
        "日用品",
        "电子产品"
    ]
    
    # 子分类
    sub_categories = {
        "饮料": ["碳酸饮料", "果汁", "茶饮料", "矿泉水"],
        "零食": ["饼干", "糖果", "膨化食品", "坚果"],
        "日用品": ["洗护用品", "清洁用品", "纸品"],
        "电子产品": ["手机配件", "电脑配件", "小家电"]
    }
    
    # 创建主分类和子分类
    for main_cat in main_categories:
        category = api.add_category(main_cat)
        category_id = category["id"]
        category_info.append({"id": category_id, "name": main_cat, "parent_id": None})
        print(f"创建主分类: {main_cat}, ID: {category_id}")
        
        # 创建子分类
        for sub_cat in sub_categories.get(main_cat, []):
            subcategory = api.add_category(sub_cat, parent_id=category_id)
            subcategory_id = subcategory["id"]
            category_info.append({"id": subcategory_id, "name": sub_cat, "parent_id": category_id})
            print(f"  创建子分类: {sub_cat}, ID: {subcategory_id}, 父分类ID: {category_id}")
    
    return category_info

def create_products(categories):
    print("\n===== 创建商品数据 =====")
    product_info = []

    # 获取所有子分类
    subcategories = [cat for cat in categories if cat["parent_id"] is not None]

    # 商品示例数据
    product_examples = {
        "碳酸饮料": [
            {"name": "可口可乐", "unit": "瓶", "price": Decimal('3.5'), "lowest_stock": 20},
            {"name": "百事可乐", "unit": "瓶", "price": Decimal('3.0'), "lowest_stock": 15},
            {"name": "雪碧", "unit": "瓶", "price": Decimal('3.0'), "lowest_stock": 15}
        ],
        "果汁": [
            {"name": "橙汁", "unit": "瓶", "price": Decimal('5.0'), "lowest_stock": 10},
            {"name": "苹果汁", "unit": "瓶", "price": Decimal('4.5'), "lowest_stock": 10}
        ],
        "茶饮料": [
            {"name": "绿茶", "unit": "瓶", "price": Decimal('3.5'), "lowest_stock": 10},
            {"name": "红茶", "unit": "瓶", "price": Decimal('3.5'), "lowest_stock": 10}
        ],
        "矿泉水": [
            {"name": "农夫山泉", "unit": "瓶", "price": Decimal('2.0'), "lowest_stock": 50},
            {"name": "恒大冰泉", "unit": "瓶", "price": Decimal('2.5'), "lowest_stock": 50}
        ],
        "饼干": [
            {"name": "奥利奥", "unit": "包", "price": Decimal('8.5'), "lowest_stock": 5},
            {"name": "趣多多", "unit": "包", "price": Decimal('7.5'), "lowest_stock": 5}
        ],
        "糖果": [
            {"name": "徐福记", "unit": "包", "price": Decimal('10.0'), "lowest_stock": 5},
            {"name": "大白兔奶糖", "unit": "包", "price": Decimal('12.0'), "lowest_stock": 5}
        ],
        "膨化食品": [
            {"name": "薯片", "unit": "包", "price": Decimal('6.0'), "lowest_stock": 10},
            {"name": "虾条", "unit": "包", "price": Decimal('5.0'), "lowest_stock": 10}
        ],
        "坚果": [
            {"name": "开心果", "unit": "包", "price": Decimal('15.0'), "lowest_stock": 5},
            {"name": "腰果", "unit": "包", "price": Decimal('18.0'), "lowest_stock": 5}
        ],
        "洗护用品": [
            {"name": "洗发水", "unit": "瓶", "price": Decimal('25.0'), "lowest_stock": 10},
            {"name": "沐浴露", "unit": "瓶", "price": Decimal('22.0'), "lowest_stock": 10}
        ],
        "清洁用品": [
            {"name": "洗衣液", "unit": "瓶", "price": Decimal('18.0'), "lowest_stock": 10},
            {"name": "洗洁精", "unit": "瓶", "price": Decimal('10.0'), "lowest_stock": 10}
        ],
        "纸品": [
            {"name": "卫生纸", "unit": "包", "price": Decimal('15.0'), "lowest_stock": 10},
            {"name": "纸巾", "unit": "包", "price": Decimal('8.0'), "lowest_stock": 10}
        ],
        "手机配件": [
            {"name": "手机壳", "unit": "个", "price": Decimal('20.0'), "lowest_stock": 10},
            {"name": "充电器", "unit": "个", "price": Decimal('35.0'), "lowest_stock": 10}
        ],
        "电脑配件": [
            {"name": "鼠标", "unit": "个", "price": Decimal('45.0'), "lowest_stock": 10},
            {"name": "键盘", "unit": "个", "price": Decimal('60.0'), "lowest_stock": 10}
        ],
        "小家电": [
            {"name": "电水壶", "unit": "个", "price": Decimal('80.0'), "lowest_stock": 10},
            {"name": "电风扇", "unit": "个", "price": Decimal('120.0'), "lowest_stock": 10}
        ]
    }
    
    # 为每个子分类创建商品
    for subcategory in subcategories:
        examples = product_examples.get(subcategory["name"], [])
        if not examples:
            continue
            
        for example in examples:
            product = api.add_product(
                example["name"], 
                subcategory["id"], 
                example["unit"], 
                example["price"], 
                0,  # 初始库存为0
                example.get("lowest_stock", 0),
                f"{example['name']}描述", 
                True
            )
            product_info.append({"id": product["id"], "name": example["name"]})
            print(f"创建商品: {example['name']}, ID: {product['id']}, 分类: {subcategory['name']}")
    
    return product_info

def create_suppliers():
    print("\n===== 创建供应商数据 =====")
    supplier_info = []
    
    # 供应商示例数据 - 增加供应商类型
    supplier_examples = [
        {
            "name": "优质饮料批发商",
            "contact": "张三",
            "phone": "13800138001",
            "wechat": "zhangsan001",
            "address": "北京市海淀区中关村",
            "type": "饮料供应商"
        },
        {
            "name": "全球零食直供",
            "contact": "李四",
            "phone": "13900139001",
            "wechat": "lisi002",
            "address": "上海市浦东新区张江高科",
            "type": "零食供应商"
        },
        {
            "name": "日用品大世界",
            "contact": "王五",
            "phone": "13700137001",
            "wechat": "wangwu003",
            "address": "广州市天河区珠江新城",
            "type": "日用品供应商"
        },
        {
            "name": "电子产品批发中心",
            "contact": "赵六",
            "phone": "13600136001",
            "wechat": "zhaoliu004",
            "address": "深圳市南山区科技园",
            "type": "电子产品供应商"
        }
    ]
    
    for example in supplier_examples:
        supplier = api.add_supplier(
            example["name"],
            example["contact"],
            example["phone"],
            example["wechat"],
            example["address"]
        )
        supplier_info.append({
            "id": supplier["id"],
            "name": example["name"],
            "type": example["type"]
        })
        print(f"创建供应商: {example['name']}, ID: {supplier['id']}")
    
    return supplier_info

def link_products_and_suppliers(products, suppliers):
    print("\n===== 建立商品和供应商关联 =====")

    for product in products:
        supplier_products = []

        # 随机选择1到3个供应商关联到商品
        selected_suppliers = random.sample(suppliers, random.randint(1, min(3, len(suppliers))))
        for supplier in selected_suppliers:
            # 为每个商品生成一个随机的成本价格（比商品售价低10%-30%）
            try:
                product_info = api.get_product(product["id"])
                if product_info:
                    sale_price = float(product_info["price"])
                    # 成本价格为售价的70%-90%
                    cost_price = round(sale_price * random.uniform(0.7, 0.9), 2)

                    supplier_products.append({
                        "id": product["id"],
                        "cost_price": cost_price
                    })
                    print(f"供应商 {supplier['name']} 关联商品 {product['name']}, 成本价: {cost_price}")
            except Exception as e:
                print(f"获取商品 {product['name']} 信息失败: {str(e)}")
                continue

        if supplier_products:
            try:
                # 更新供应商的商品报价
                api.update_supplier_products(supplier["id"], supplier_products)
                print(f"供应商 {supplier['name']} 成功关联了 {len(supplier_products)} 个商品")
            except Exception as e:
                print(f"供应商 {supplier['name']} 关联商品失败: {str(e)}")

def create_customers():
    print("\n===== 创建客户数据 =====")
    customer_ids = []
    
    # 客户示例数据
    customer_examples = [
        {"contact": "陈一", "phone": "15800158001", "wechat": "chenyi001"},
        {"contact": "林二", "phone": "15900159001", "wechat": "liner002"},
        {"contact": "黄三", "phone": "15700157001", "wechat": "huangsan003"},
        {"contact": "刘四", "phone": "15600156001", "wechat": "liusi004"},
        {"contact": "吴五", "phone": "15500155001", "wechat": "wuwu005"}
    ]
    
    for example in customer_examples:
        customer = api.add_customer(
            example["contact"],
            example["phone"],
            example["wechat"],
        )
        customer_ids.append({"id": customer["id"], "contact": example["contact"]})
        print(f"创建客户: {example['contact']}, ID: {customer['id']}")
    
    return customer_ids

def create_purchases_and_update_status(suppliers, products, user_ids):
    print("\n===== 创建采购单并更新状态 =====")
    purchases = []

    for i in range(5):  # 创建5个采购单
        supplier = random.choice(suppliers)
        user_id = random.choice(user_ids)

        items = []
        selected_products = random.sample(products, random.randint(2, 4))
        for product in selected_products:
            quantity = random.randint(10, 50)
            unit_price = Decimal(str(random.uniform(5.0, 100.0))).quantize(Decimal('0.01'))
            items.append({
                "product_id": product["id"],
                "quantity": quantity,
                "unit_price": unit_price
            })

        try:
            purchase = api.add_purchase(supplier["id"], user_id, items)
            purchases.append(purchase)
            print(f"创建采购单: ID: {purchase['id']}, 供应商: {supplier['name']}")

            # 模拟更新状态为已入库
            api.update_purchase(purchase["id"], PurchaseStatus.RECEIVED)
            print(f"采购单 {purchase['id']} 状态更新为: 已入库")
        except Exception as e:
            print(f"创建采购单失败: {str(e)}")

    return purchases

def get_all_purchase_batches(purchases):
    """获取所有采购批次数据"""
    print("\n===== 获取所有采购批次数据 =====")
    all_batches = []

    # 从现有的采购单中提取批次信息
    for purchase in purchases:
        for item in purchase.get("items", []):
            batch = {
                "id": item["id"],
                "product_id": item["product_id"],
                "quantity_total": item["quantity"],
                "quantity_available": item["quantity"],
                "cost_price": item["unit_price"]
            }
            all_batches.append(batch)
            print(f"获取批次: {batch}")

    return all_batches

def create_sales_and_update_status(purchase, customers, products, user_ids):
    print("\n===== 创建销售单并更新状态 =====")
    sales = []

    # 获取所有采购批次
    all_batches = get_all_purchase_batches(purchase)

    for i in range(8):  # 创建8个销售单
        customer = random.choice(customers)
        user_id = random.choice(user_ids)

        items = []
        selected_products = random.sample(products, random.randint(1, 3))
        for product in selected_products:
            # 从所有批次中筛选出与当前商品相关的批次
            product_batches = [batch for batch in all_batches if batch["product_id"] == product["id"]]
            if not product_batches:
                print(f"商品 {product['id']} 无可用批次，跳过")
                continue

            batch = random.choice(product_batches)
            quantity = random.randint(1, batch["quantity_available"])
            unit_price = batch["cost_price"] * Decimal('1.2')  # 销售价为成本价的1.2倍

            items.append({
                "product_id": product["id"],
                "quantity": quantity,
                "unit_price": unit_price
            })

        if not items:
            print("未能为销售单选择有效商品，跳过创建")
            continue

        try:
            sale = api.add_sale(customer["id"], user_id, items)
            sales.append(sale)
            print(f"创建销售单: ID: {sale['id']}, 客户: {customer['contact']}")

            # 模拟更新状态为已付款
            random_payment = random.choice(list(PaymentMethod))
            api.update_sale(sale["id"], SaleStatus.PAID, random_payment)
            print(f"销售单 {sale['id']} 状态更新为: 已付款")
        except Exception as e:
            print(f"创建销售单失败: {str(e)}")

    return sales

# 添加采购退货和销售退货的测试数据生成函数
def create_purchase_returns(purchases, user_ids):
    print("\n===== 创建采购退货单数据 =====")
    
    # 为30%的采购单创建退货记录
    for purchase in random.sample(purchases, max(len(purchases) // 3, 1)):
        user_id = random.choice(user_ids)
        
        # 随机选择采购项进行退货
        return_items = []
        
        if "items" not in purchase:
            print(f"采购单 {purchase['id']} 没有items数据，跳过创建退货单")
            continue
            
        for item in purchase["items"]:
            # 50%的概率对此项进行退货
            if random.random() < 0.5:
                return_quantity = random.randint(1, item["quantity"])
                
                return_items.append({
                    "purchase_item_id": item["id"],
                    "quantity": return_quantity,
                    "unit_price": item["unit_price"],
                    "product": item["product"]
                })
        
        if return_items:
            try:
                # 创建采购退货单
                purchase_return = api.add_purchase_return(
                    purchase["id"],
                    user_id,
                    return_items,
                    "质量问题退货",
                    datetime.now()
                )
                print(f"创建采购退货单: 采购单ID: {purchase['id']}")
            except Exception as e:
                import traceback
                traceback.print_exc()
                print(f"创建采购退货单失败: {str(e)}")

def create_sale_returns(sales, user_ids):
    print("\n===== 创建销售退货单数据 =====")
    
    # 为20%的销售单创建退货记录
    for sale in random.sample(sales, max(len(sales) // 5, 1)):
        user_id = random.choice(user_ids)
        
        # 随机选择销售项进行退货
        return_items = []
        
        if "items" not in sale:
            print(f"销售单 {sale['id']} 没有items数据，跳过创建退货单")
            continue
            
        for item in sale["items"]:
            # 40%的概率对此项进行退货
            if random.random() < 0.4:
                return_quantity = random.randint(1, item["quantity"])
                
                return_items.append({
                    "sale_item_id": item["id"],
                    "quantity": return_quantity,
                    "unit_price": item["unit_price"]
                })
        
        if return_items:
            try:
                # 创建销售退货单
                sale_return = api.add_sale_return(
                    sale["id"],
                    user_id,
                    return_items,
                    "客户退货",
                    datetime.now()
                )
                print(f"创建销售退货单: 销售单ID: {sale['id']}")
            except Exception as e:
                import traceback
                traceback.print_exc()
                print(f"创建销售退货单失败: {str(e)}")

def create_purchase_batches(purchases):
    print("\n===== 创建采购批次数据 =====")
    for purchase in purchases:
        for item in purchase.get("items", []):
            batch = api.add_purchase_batch(
                purchase_item_id=item["id"],
                quantity_total=item["quantity"],
                quantity_available=item["quantity"],
                cost_price=item["unit_price"]
            )
            print(f"创建采购批次: ID: {batch['id']}, 采购项ID: {item['id']}")

def create_sale_item_batches(sales):
    print("\n===== 创建销售项批次数据 =====")
    for sale in sales:
        for item in sale.get("items", []):
            # 假设每个销售项随机关联一个采购批次
            purchase_batches = api.get_purchase_batches_by_product(item["product_id"])
            if not purchase_batches:
                print(f"商品 {item['product_id']} 无可用批次，跳过")
                continue

            batch = random.choice(purchase_batches)
            sale_item_batch = api.add_sale_item_batch(
                sale_item_id=item["id"],
                purchase_batch_id=batch["id"],
                quantity=item["quantity"],
                cost_price=batch["cost_price"],
                total_cost=batch["cost_price"] * item["quantity"]
            )
            print(f"创建销售项批次: ID: {sale_item_batch['id']}, 销售项ID: {item['id']}")

if __name__ == "__main__":
    sqldbpath = config.DB_STRING.split("///")[1] if config.DB_STRING.startswith("sqlite") else ""
    if sqldbpath and os.path.exists(sqldbpath):
        os.unlink(sqldbpath)
    Base.metadata.create_all(engine)
    # 创建测试数据
    create_test_data()